﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Collections;
using System.Text.RegularExpressions;
using Open_MUD.Kernel.Interface.Client;

namespace Open_MUD.Kernel.Interface.Conns
{
    class TelnetConnection:Cliente
    {
        Socket socket;
        StreamReader Reader;
        StreamWriter Writer;
        object objlock = new object();
        
        override
        protected String leerLinea()
        {
            return Reader.ReadLine();
        }

        override
        protected void finbucle()
        {
            socket.Close();
        }

        public override void doprompt(string prompt)
        {
            base.doprompt(prompt);
            lock (objlock)
            {
                Writer.Write(prompt);
                Writer.Flush();
            }
        }

        public override String render(string msg)
        {
            msg = base.render(msg);
            msg = parseMsg(msg);
            lock (objlock)
            {
                Writer.WriteLine(msg);
                Writer.Flush();
            }
            return msg;
        }

        internal TelnetConnection(Socket socket):base()
        {
            this.socket = socket;
            Reader = new StreamReader(new NetworkStream(socket, false),Encoding.Default, false);            
            Writer = new StreamWriter(new NetworkStream(socket, true),Encoding.Default);
            new Thread(ClientLoop).Start();
        }

        // TRATAMIENTO VISUAL DEL CLIENTE TELNET
        private String parseMsg(string msg)
        {   
            return tratar(msg);
        }

        const int MAXCOLOR = 10;
        private string esc = (char)27 + "[";       

        private string tratar(string text)
        { // Parsing de caracteres especiales...            
            //string color = (char)27 + "[XXm";
            string ret = "", pend = "";
            char current;
            int i = 0, ctrwatchdog = 0;
            int control = 0; // 0:normal 1:% 2:%^ 3:%^AZaz% 4:%^AZaz%^ 5:volcar error
            string pendiente = "";

            while (i < text.Length)
            {
                current = text[i];
                if (current == '%' && (control == 0 || control == 3))
                {
                    if (control == 0)
                    {
                        control = 1;
                    }
                    else if (control == 1)
                        control = 99;
                    else if (control == 3)
                        control = 4;

                }
                else if (current == '^' && (control == 1 || control == 4))
                {
                    if (control == 1)
                        control = 2;
                    else if (control == 4)
                        control = 5;

                }
                else if (control == 2)
                    control = 3;


                if (control == 0)
                {
                    if (!pendiente.Equals(""))
                    {
                        ret += pendiente;
                        pendiente = "";
                    }
                    ret += current;
                }
                else if (control == 3)
                {
                    pendiente += current;
                    ctrwatchdog++;
                }
                else if (control == 5)
                {
                    pend = pendiente.ToLower();

                    if (!pend.StartsWith("b_"))
                        switch (pend)
                        {
                            case "reset": ret += esc + "0" + "m"; break;
                            case "bold": ret += esc + "1" + "m"; break;
                            case "black": ret += esc + "30" + "m"; break;
                            case "red": ret += esc + "31" + "m"; break;
                            case "green": ret += esc + "32" + "m"; break;
                            case "yellow": ret += esc + "33" + "m"; break;
                            case "blue": ret += esc + "34" + "m"; break;
                            case "magenta": ret += esc + "35" + "m"; break;
                            case "cyan": ret += esc + "36" + "m"; break;
                            case "white": ret += esc + "37" + "m"; break;
                            case "italic": ret += esc + "3" + "m"; break;
                            case "underline": ret += esc + "4" + "m"; break;
                            case "ret": ret += "\r\n"; break;
                            default: ret += pendiente; break; // Si no es un color, pendiente conserva su valor anterior
                        }
                    else
                        switch (pend)
                        {
                            case "b_black": ret += esc + "40" + "m"; break;
                            case "b_red": ret += esc + "41" + "m"; break;
                            case "b_green": ret += esc + "42" + "m"; break;
                            case "b_yellow": ret += esc + "43" + "m"; break;
                            case "b_blue": ret += esc + "44" + "m"; break;
                            case "b_magenta": ret += esc + "45" + "m"; break;
                            case "b_cyan": ret += esc + "46" + "m"; break;
                            case "b_white": ret += esc + "47" + "m"; break;
                            default: ret += pendiente; break;
                        }
                    pendiente = "";
                    ctrwatchdog = 0;
                    control = 3;
                }
                if ((control == 1 || control == 4) && (current != '%'))
                {
                    pendiente += "%" + current;
                    control = 0;
                    ctrwatchdog = 0;
                }
                if (ctrwatchdog > MAXCOLOR)
                {
                    ctrwatchdog = 0;
                    ret += pendiente;
                    pendiente = "";
                    control = 0;
                }

                i++;
            }

            if (!pendiente.Equals(""))
            {
                ret += pendiente;
            }
            if (control == 1) // Terminó en Tanto por ciento
                ret += "%";
            return ret + esc + "0m";
        }
    }
}
